from rest_framework import generics, viewsets
from rest_framework import permissions
from rest_framework.response import Response
from rest_framework import status
from rest_framework import filters
from oauth2_provider.contrib.rest_framework import TokenHasScope
from .models import MyUser
from .permissions import CheckOperationPerm, IsOwnerOrReadOnly
from .serializers import MyUserListSerializer, MyUserDetailSerializer, ChangePasswordSerializer
from .serializers import CreateUserSerializer, EmailSerializer, LoginSerializer
from .serializers import AreaListSerializer, HospitalListSerializer, AreaOnlySerializer

from projects.models import ClinicalProjects

from django.core.mail import send_mail

from django.conf import settings

from .utils import create_password

import random
import logging
logger = logging.getLogger('email')


class UserView(generics.CreateAPIView):
    """
    post - 创建用户
    """
    serializer_class = CreateUserSerializer
    permission_classes = [permissions.AllowAny]


class LoginView(generics.GenericAPIView):
    """
    post - 登录
    """
    serializer_class = LoginSerializer
    permission_classes = [TokenHasScope, ]
    required_scopes = ['users']

    def post(self, request, *args, **kwargs):

        serializer = self.serializer_class(data=request.data,
                                           context={'request': request})
        serializer.is_valid(raise_exception=True)

        return Response(serializer.data)


class MyUserList(generics.ListAPIView):
    """
        get:
        获取所有 用户 列表
    """
    permission_classes = [TokenHasScope, IsOwnerOrReadOnly]
    required_scopes = ['users']
    queryset = MyUser.objects.all()
    serializer_class = MyUserListSerializer
    filter_backends = (filters.SearchFilter,)
    search_fields = ('$user_name', '$phone')


class MyUserDetail(generics.RetrieveUpdateAPIView):
    """
        get:
        获取该 用户 的详情

        put:
        整体更新该 用户.

        patch:
        部分更新该 用户.
    """
    permission_classes = [TokenHasScope, CheckOperationPerm]
    required_scopes = ["users"]
    queryset = MyUser.objects.all()
    serializer_class = MyUserDetailSerializer


class UpdatePassword(generics.GenericAPIView):
    """
        put:
        更新密码，需要提供旧密码
    """
    permission_classes = [TokenHasScope, CheckOperationPerm]
    required_scopes = ['users']

    def get_object(self, queryset=None):
        return self.request.user

    def get_queryset(self):
        user = self.request.user
        return user.accounts.all()

    def get_serializer_class(self):
        return ChangePasswordSerializer

    def put(self, request, *args, **kwargs):
        self.object = self.get_object()
        serializer = ChangePasswordSerializer(data=request.data)

        serializer.is_valid(raise_exception=True)

        if serializer.is_valid():
            # Check old password
            old_password = serializer.data.get("old_password")
            if not self.object.check_password(old_password):
                return Response({"old_password": ["旧密码错误"]},
                                status=status.HTTP_400_BAD_REQUEST)
            # set_password also hashes the password that the user will get
            self.object.set_password(serializer.data.get("new_password"))
            self.object.save()
            return Response({"status": "success"}, status=status.HTTP_200_OK)

        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)


class SendEmailView(generics.CreateAPIView):

    permission_classes = [permissions.AllowAny, ]

    serializer_class = EmailSerializer

    def create(self, request, *args, **kwargs):
        serializer = self.serializer_class(data=request.data)
        serializer.is_valid(raise_exception=True)
        email = serializer.validated_data['email']

        content3 = '<a href="%s">跳转至临床流调登录页</a>' % settings.WEB_STATION

        try:
            # update password
            try:
                sign = create_password()
            except Exception as e:
                raise ValueError(e)

            content4 = '<p><span style="color: red;font-weight: bold">注意</span>:请用该密码登录系统，并尽快修改成您容易记忆的密码</p>'
            content44 = '<p><span style="color: red;font-weight: bold">注意</span>:使用该密码登录后, 尽快修改您的密码, 方便您下次登录</p>'

            try:
                user = MyUser.objects.get(email=email)
            except MyUser.DoesNotExist:
                raise

            if user:
                user.set_password(sign)
                try:
                    user.save()
                except Exception as e:
                    raise e

            content2 = '<p>亲爱的%s, 您修改后的密码为<span style="font-weight: bold">%s</span></p>' % (
                user.user_name, sign)

            content1 = '<h2>欢迎%s使用中医妇科临床流调系统:</h2>' % user.user_name

            content_alert = [content4, content44]

            alert = content_alert[random.randint(0, 1)]

            html_content = ''.join([content1, content2, alert, content3])
            # send email
            send_mail('中医妇科临床流调',
                      '',
                      settings.EMAIL_HOST_USER,
                      [email],
                      html_message=html_content)

        except Exception as e:
            logger.error('邮件发送失败原因: %s' % e)
            return Response({'msg': '密码无法修改, 请重试'}, status=status.HTTP_400_BAD_REQUEST)

        # 效率高于上面的方法
        # send_mass_mail((('中医妇科临床流调',
        #                  'a',
        #                  settings.EMAIL_HOST_USER,
        #                  [email]),), fail_silently=False)
        logger.info('邮件发送成功, %s 新的密码为: %s' % (email, sign))
        return Response({'msg': '邮件发送成功, 新的密码请查看邮件'})


class AreaListOfView(viewsets.ModelViewSet):
    permission_classes = []

    queryset = MyUser.objects.values('area').distinct()

    pagination_class = None

    serializer_class = AreaOnlySerializer

    def create(self, request, *args, **kwargs):
        serializer = self.get_serializer(data=request.data)

        serializer.is_valid(raise_exception=True)

        prj_code = serializer.validated_data['prj_code']

        cli_obj = ClinicalProjects.objects.get(prj_code=prj_code)

        list_of_area = cli_obj.relusers.values('area').distinct()

        return Response(list_of_area)


class AreaListView(viewsets.ModelViewSet):
    permission_classes = []
    # required_scopes = ['users']
    queryset = MyUser.objects.values('area').distinct()

    pagination_class = None

    def get_serializer_class(self):
        if self.action == 'update':
            return HospitalListSerializer
        else:
            return AreaListSerializer

    def create(self, request, *args, **kwargs):
        '''
        :return null or a list about hospital
        '''
        serializer = self.get_serializer(data=request.data)

        serializer.is_valid(raise_exception=True)

        area = serializer.validated_data['area']

        prj_code_serialzer = serializer.validated_data['prj_code']

        cli_obj = ClinicalProjects.objects.get(prj_code=prj_code_serialzer)

        list_of_hospital = cli_obj.relusers.filter(area=area).values('hospital').distinct()

        return Response(list_of_hospital)

    def update(self, request, *args, **kwargs):
        '''
        :return null or a list about user_name and id
        '''
        serializer = self.get_serializer(data=request.data)

        serializer.is_valid(raise_exception=True)

        prj_code_serialzer = serializer.validated_data['prj_code']

        hospital = serializer.validated_data['hospital']

        cli_obj = ClinicalProjects.objects.get(prj_code=prj_code_serialzer)

        list_of_users = cli_obj.relusers.filter(hospital=hospital).values('user_name', 'id')

        return Response(list_of_users)
